const vscode = require('vscode')
const fs = require('fs-extra')
const path = require('path')

// 模板信息接口
class Template {
  constructor (name, templatePath) {
    this.name = name
    this.path = templatePath
  }
}

// 模块级变量
const TEMPLATE_STORAGE_KEY = 'businessPageTemplates.storagePath'
const TEMPLATES_KEY = 'businessPageTemplates.templates'

function activate (context) {
  console.log('插件已激活')

  const storagePath = context.globalStorageUri?.fsPath || context.storagePath
  if (!storagePath) {
    vscode.window.showErrorMessage('无法初始化模板存储路径')
    return
  }

  context.globalState.setKeysForSync([TEMPLATE_STORAGE_KEY, TEMPLATES_KEY])

  // 确保模板存储目录存在
  const templatesDir = path.join(storagePath, 'templates')
  fs.ensureDirSync(templatesDir)

  console.log('templatesDir=', templatesDir)

  /* ------------------------------------- 保存模版功能 Strat ------------------------------------------------------------ */
  let saveAsTemplate = vscode.commands.registerCommand(
    'saveAsTemplate',
    async uri => {
      // vscode.window.showInformationMessage('保存模版功能已触发！')
      console.log('选中的路径:', uri.fsPath)

      const selectedResource = uri //getSelectedResource()
      if (!selectedResource) {
        vscode.window.showWarningMessage('请在资源管理器中选择一个文件或文件夹')
        return
      }

      try {
        let inputTemplateName = await showInputBox('请输入模板名称', '模板名称')
        if (!inputTemplateName) {
          return // 用户按下了ESC取消
        }

        try {
          const sourcePath = selectedResource.fsPath
          const {
            success: isContinue,
            templateFileName: templateDir,
            templateName
          } = await checkTemplateAndNormalizeTemplateName(
            sourcePath,
            templatesDir,
            inputTemplateName
          )

          if (!isContinue) {
            return // 用户取消输入或不覆盖
          }

          // 复制文件/文件夹到模板目录
          fs.copySync(sourcePath, templateDir)

          // 更新模板列表
          const templates = context.globalState.get(TEMPLATES_KEY, [])
          const existingIndex = templates.findIndex(
            t => t.name === templateName
          )
          if (existingIndex > -1) {
            templates.splice(existingIndex, 1)
          }

          templates.push(new Template(templateName, templateDir))
          await context.globalState.update(TEMPLATES_KEY, templates)

          vscode.window.showInformationMessage(`模板【${templateName}】保存成功`)
        } catch (error) {
          vscode.window.showErrorMessage(`保存模板失败: ${error.message}`)
        }
      } catch (error) {
        console.error('请求失败:', err)
      }
    }
  )

  context.subscriptions.push(saveAsTemplate)
  /* ------------------------------------- 保存模版功能 End------------------------------------------------------------ */

  /* ------------------------------------- 新建页面从模版功能 Strat------------------------------------------------------------ */
  // 新建页面从模版功能
  let createNewPageFromTemplate = vscode.commands.registerCommand(
    'createNewPageFromTemplate',
    async uri => {
      // vscode.window.showInformationMessage('新建页面从模版功能已触发！')

      console.log('选中的路径:', uri.fsPath)

      try {
        // 1. 获取选中的文件夹，如果是文件则获取其所在的文件夹
        const selectedPath = uri.fsPath
        const isFile = fs.statSync(selectedPath).isFile()
        const targetDir = isFile ? path.dirname(selectedPath) : selectedPath

        // 2. 获取所有已保存的模板列表，并以下拉形式展示
        const templates = context.globalState.get(TEMPLATES_KEY, [])
        if (templates.length === 0) {
          vscode.window.showWarningMessage('没有可用的模板，请先保存模板。')
          return
        }

        const templateNames = templates.map(template => template.name)
        const selectedTemplateName = await vscode.window.showQuickPick(
          templateNames,
          {
            placeHolder: '请选择一个模板',
            ignoreFocusOut: true
          }
        )

        if (!selectedTemplateName) {
          return // 用户取消选择
        }

        const selectedTemplate = templates.find(
          template => template.name === selectedTemplateName
        )

        // 3. 用户输入新页面名称
        const newPageName = await vscode.window.showInputBox({
          prompt: '请输入新页面名称',
          placeHolder: '新页面名称',
          ignoreFocusOut: true,
          validateInput: value => {
            if (!value || value.trim().length === 0) {
              return '新页面名称不能为空'
            }
            return null
          }
        })

        if (!newPageName) {
          return // 用户取消输入
        }

        // 如果选择的模版是文件，考虑后缀问题
        const tempIsFile = fs.statSync(selectedTemplate.path).isFile()

        const fileExt = tempIsFile ? path.extname(selectedTemplate.path) : ''
        const finalPageName = fileExt
          ? appendFileExtension(newPageName, fileExt)
          : newPageName

        // 4. 将模板内容复制到新页面所在的文件夹中，并重命名为用户输入的新名称
        const newPagePath = path.join(targetDir, finalPageName)
        fs.copySync(selectedTemplate.path, newPagePath)

        vscode.window.showInformationMessage(`新页面创建成功: ${newPagePath}`)
      } catch (error) {
        vscode.window.showErrorMessage(`新页面创建失败: ${error.message}`)
      }
    }
  )

  context.subscriptions.push(createNewPageFromTemplate)
  /* ------------------------------------- 新建页面从模版功能 End------------------------------------------------------------ */

  let clearTemplate = vscode.commands.registerCommand(
    'clearTemplate',
    async uri => {
      // vscode.window.showInformationMessage('清空模版已触发！')
      try {
        await context.globalState.update(TEMPLATES_KEY, [])

        vscode.window.showInformationMessage(`清空模版成功`)
      } catch (error) {
        vscode.window.showErrorMessage(`清空模版失败: ${error.message}`)
      }
    }
  )
  context.subscriptions.push(clearTemplate)
}

// 获取当前 VS Code 中激活的文件的本地文件路径
// vscode.window.activeTextEditor: 获取当前激活的文本编辑器（即用户正在看或正在编辑的那个标签页）
function getSelectedResource () {
  // 获取右键菜单选中的文件或文件夹路径
  const selection = vscode.window.activeTextEditor?.document.uri
  const pathSelection = selection
    ? vscode.Uri.file(selection.fsPath)
    : undefined
  console.log('当前选中的资源:', pathSelection)
  return pathSelection
}

// 清理模板名称，移除非法字符
function sanitizeTemplateName (name) {
  // 移除非法文件名字符并替换为空格
  return name.replace(/[<>:"\/\\|?*\x00-\x1F]/g, '').trim()
}

// export function deactivate () {
//   // 注销时清理资源
// }

function appendFileExtension (templateName, fileExt) {
  // 参数校验
  if (typeof templateName !== 'string' || typeof fileExt !== 'string') {
    throw new TypeError('Both parameters must be strings.')
  }

  // 确保扩展名以 . 开头
  const normalizedFileExt = fileExt.startsWith('.') ? fileExt : `.${fileExt}`

  // 避免重复添加相同的扩展名
  if (templateName.endsWith(normalizedFileExt)) {
    return templateName
  }

  return templateName + normalizedFileExt
}

function showInputBox (prompt = '请输入模板名称', placeHolder = '模板名称') {
  return vscode.window.showInputBox({
    prompt: prompt,
    placeHolder: placeHolder,
    ignoreFocusOut: true,
    validateInput: value => {
      if (!value || value.trim().length === 0) {
        return '输入不能为空'
      }
      return null
    }
  })
}

/**
 * 规范化模板名称
 * @param {*} sourcePath 选择的文件/文件夹路径
 * @param {*} templatesDir 模板存储目录
 * @param {*} templateName 模板名称
 * @returns {string} 模板存储路径 = 模板存储目录 + 模板名称（如果是文件，则含后缀）
 */
function normalizeTemplateName (sourcePath, templatesDir, templateName) {
  // 如果选中的是文件，重命名为模板名称加上原文件后缀
  const isFile = fs.statSync(sourcePath).isFile()
  templateName = sanitizeTemplateName(templateName)
  if (isFile) {
    const fileExt = path.extname(sourcePath)
    templateName = appendFileExtension(templateName, fileExt)
  }
  const templateDir = path.join(templatesDir, templateName)
  return templateDir
}

async function checkTemplateAndNormalizeTemplateName (sourcePath, templatesDir, templateName) {
  const finalTemplateName  = normalizeTemplateName(sourcePath, templatesDir, templateName)

  // 检查模板是否已存在
  if (fs.existsSync(finalTemplateName)) {
    const overwrite = await vscode.window.showWarningMessage(
      `模板 "${templateName}" 已存在，是否覆盖？`,
      { modal: true },
      '是',
      '否'
    )

    if (overwrite === '是') {
      fs.removeSync(templateFileName)
      return { success: true, templateFileName: templateFileName, templateName }
    } else {
      // 重新弹出模板名称输入框
      const inputTemplateName = await showInputBox('请输入新的模板名称', '模板名称')
      if (!inputTemplateName) {
        return { success: fasle, canceled: true } // 用户取消输入
      }

      return await checkTemplateAndNormalizeTemplateName(sourcePath, templatesDir, inputTemplateName)
    }
  } else {
    return { success: true, templateFileName: finalTemplateName, templateName }
  }
}

module.exports = {
  activate
}
